import React, { Component, Fragment } from 'react';
import { Form, Row, Col, Checkbox, Button, message, Modal, Input  } from 'antd';
import Link from 'umi/link';
import { phone as phoneReg, trim as trimReg, regRules} from '@/utils/regexp';
import SparkMD5 from 'spark-md5';
import withRedirect from '@/utils/withRedirect';
import withRouter from 'umi/withRouter';
import { connect } from 'dva';
import LoginWrapper from '@/components/LoginWrapper';
import { setToken, getAccount, setAccount, removeAccount } from '@/utils/cookies';
import style from './style.less'
const FormItem = Form.Item;
const { AccountFormItem, GetYCodeFormItem, PasswordFormItem } = LoginWrapper;
const formItemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 5 },
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 12 },
  },
};
@connect(({ loading: { models: { login } } }) => ({
  loading: !!login, //!!loading['effects']['login/queryGeetestInfo'],
}))
@Form.create()
@withRouter
class LoginForm extends Component {

  constructor(props) {
    super(props);
    this.state = {
      geeTestVisible: null,
      smsModalVisible: false,
      actionId: '', //后台给的标识
    };
    this.geeTestNode = React.createRef();
  }

  setSmSModalVisible(smsModalVisible) {
    this.mounted && this.setState({ smsModalVisible });
  }

  initGeetest = () => {
    const { dispatch } = this.props
    dispatch({
      type:'login/queryGeetestInfo',
    })
    .then(data => {
      data && this.mounted && this.setState({
        actionId: data.id
      },()=>{
          //文档：https://docs.geetest.com/install/deploy/client/web#onError-callback
          //通过引入gt.js `initGeetest` 初始化函数
          window.initGeetest(
            {
              // 以下 4 个配置参数为必须，不能缺少
              gt: data.gt,
              challenge: data.challenge,
              offline: !data.success, // 表示用户后台检测极验服务器是否宕机
              new_captcha: data.new_captcha, // 用于宕机时表示是新验证码的宕机
              product: 'float', // 产品形式，包括：float，popup, custom
              width: '100%',
              next_width: '260px',
              area: '#root',
              bg_color: 'black',
              // 更多前端配置参数说明请参见：http://docs.geetest.com/install/client/web-front/
            },
            captchaObj => {
              // 这里可以调用验证实例 captchaObj 的实例方法
              captchaObj.onReady(() => {
                this.mounted && this.setState({
                  geeTestVisible: 'true',
                  captchaObj,
                },() => {
                  this.clearGeeTestArea();
                  //将验证按钮插入到宿主页面中captchaBox元素内
                  captchaObj.appendTo(this.refs.geeTestNode);
                });
              })
              // .onSuccess(()=>{

              // })
              // .onError(()=>{

              // })
              ;
            }
          );
      })

    })
    .catch(err=>{
      message.error(`${err}`);
    })

  };

  // componentDidMount() {
  //   this.initGeetest();
  // }

  clearGeeTestArea = () => {
    this.refs.geeTestNode.innerHTML = '';
  };

  resetGeeTest = () => {
    if (this.state.captchaObj) {
      /**如果已经存在，重置*/
      this.state.captchaObj.reset();
    } else {
      this.initGeetest();
    }
  };

  handleSubmit = e => {
    e && e.preventDefault();
    const { dispatch, form, loginType, history } = this.props;

    let geeTestResult;
    const { state } = this;
    if (state.geeTestVisible  === 'true') {
      if (state.captchaObj) {
        geeTestResult = state.captchaObj.getValidate();
      } else {
        geeTestResult = undefined;
      }
    }

    form.validateFields((err, fieldsValue) => {
      if (!err) {
        // 登录类型 1手机号登录 2邮箱账号登录 ,
        // values.loginType = loginType === 'pwd' ? 2 : 1;
        let values = {
          ...fieldsValue,
        };

        //如果是mac和ip地址发生变化就需要输入验证码
        if(state.smsModalVisible){
          this.setSmSModalVisible(false)
        }
        //如果是密码发生错误第二次就要进行行为验证
        if(state.geeTestVisible === 'true') {
            if (geeTestResult) {
              values = {
                ...values,
                actionId: this.state.actionId,
                challenge: geeTestResult.geetest_challenge,
                validate: geeTestResult.geetest_validate,
                seccode: geeTestResult.geetest_seccode,
              };
            }else{
              message.error('请完成安全验证!');
              return
            }
        }

        let type = 'login/loginWithPwd';
        if (loginType === 'pwd') {
          values.password = SparkMD5.hash(values.password);
        }
        if (loginType === 'msg') {
          type = 'login/loginWithSms';
        }
        dispatch({
          type,
          payload: values,
        })
          .then(({ token, validate, msg }) => {

            if(validate === 'action'){
              this.mounted && this.setState({
                geeTestVisible: 'false'
              },() => {
                message.error(msg);
                this.initGeetest()
                return false
              });
            }
            if(validate === 'sms'){
                message.error(msg);
                this.setSmSModalVisible(true)
                return false
            }

            if(token){
              setToken(token);
              message.success('登录成功');
              this.resetGeeTest()
              history.push(`/dashboard`)
            }

          })
          .catch(errMsg => {
            message.error(errMsg);
            this.resetGeeTest()
          });

        if (values.remember) {
          setAccount(loginType === 'pwd' ? values.username : values.mobile);
        } else {
          removeAccount();
        }
      }
    });
  };

  mounted=true
  componentWillUnmount(){
      this.mounted=null;
  }

  render() {
    const {
      form,
      form: { getFieldDecorator },
      userType,
      loginType,
      loading,
    } = this.props;
    const initialAccount = getAccount();
    const accountRules =
      loginType === 'msg'
        ? {
            rules: [
              {
                required: true,
                message: '请输入正确的手机号',
                pattern: phoneReg,
              },
            ],
            placeholder: '请输入手机号',
          }
        : {};
    return (
      <div className="form-wrapper">
        <div className="tabs">
          <Link
            to={withRedirect(
              `/user/login?userType=${userType}&loginType=${loginType === 'pwd' ? 'msg' : 'pwd'}`
            )}
            className={loginType === 'pwd' ? 'active' : ''}
          >
            密码登录
          </Link>
          <Link
            to={withRedirect(
              `/user/login?userType=${userType}&loginType=${loginType === 'pwd' ? 'msg' : 'pwd'}`
            )}
            className={loginType === 'msg' ? 'active' : ''}
          >
            验证码登录
          </Link>
        </div>
        <Form onSubmit={this.handleSubmit}>

          {loginType === 'pwd' && (
            <Fragment>
              <AccountFormItem
                form={form}
                disabled={loading}
                focus
                id="username"
                initialValue={initialAccount}
                {...accountRules}
              />

              <PasswordFormItem disabled={loading} focus={!!initialAccount} form={form} />
            </Fragment>
          )}
          {loginType === 'msg' && (
            <Fragment>
              <AccountFormItem
                form={form}
                disabled={loading}
                focus
                id="mobile"
                initialValue={initialAccount}
                {...accountRules}
              />
                <GetYCodeFormItem
                  disabled={loading}
                  id="code"
                  validField="mobile"
                  type="phone"
                  serviceType={1}
                  focus={!!initialAccount}
                  form={form}
                />
            </Fragment>
          )}
          <FormItem>
          {
              this.state.geeTestVisible === 'false' ?
                    <div ref={node => this.wait = node} className={style.show}>
                        <div className={style.loading}>
                            <div className={style.loadingDot}></div>
                            <div className={style.loadingDot}></div>
                            <div className={style.loadingDot}></div>
                            <div className={style.loadingDot}></div>
                        </div>
                    </div>
                  :
                  (
                    <div ref='geeTestNode' style={{ marginBottom: 15 }}></div>
                  )
            }
          </FormItem>
          <Row>
            <Col span={12} className="tl">
              <FormItem>
                {getFieldDecorator('remember', {
                  valuePropName: 'checked',
                  initialValue: !!initialAccount,
                })(<Checkbox disabled={loading}>记住帐号</Checkbox>)}
              </FormItem>
            </Col>
            <Col span={12} className="tr">
              <FormItem>
                <Link to="/user/resetPassword">
                  <span className="link">忘记密码</span>
                </Link>
              </FormItem>
            </Col>
          </Row>
          <div className="tc">
            <Button
              className="primary-button"
              disabled={loading}
              htmlType="submit"
              loading={loading}
            >
              {loading ? '请稍候' : '登录'}
            </Button>
          </div>

          {
            this.state.smsModalVisible && (
            <Modal
              title="请输入收到的验证码"
              centered
              visible={this.state.smsModalVisible}
              onOk={() => this.handleSubmit()}
              onCancel={() => this.setSmSModalVisible(false)}
              destroyOnClose
              maskClosable={false}
              confirmLoading={loading}
              //width={600}
              cancelText="取消"
              okText="确定"
              >
              <Row>
                    <Col span={24}>
                      <FormItem label="验证码" {...formItemLayout}>
                        {getFieldDecorator('smsCode', {
                          //initialValue: ,
                          rules: [
                            {
                              required: true,
                              message: '请输入验证码',
                              pattern: trimReg,
                            },
                            {
                              len: 6,
                              message: '请输入6位验证码',
                            },
                          ],
                        })(
                          <Input
                            className="login-input"
                            //disabled={disabled}
                            placeholder="请输入验证码"
                            ref={ref => (this.codeInput = ref)}
                          />
                        )}
                      </FormItem>
                    </Col>
                  </Row>
              </Modal>
              )
          }
        </Form>
      </div>
    );
  }
}
export default LoginForm;
